/*
visqrt
Copyright (C) 2010  Bhupendra Aole

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/
/*
 * File: CameraPinhole.java
 * Author: Bhupendra Aole
 * Date: Aug 28, 2010: 
 * 
 * Revisions:
 * ----------
 */

package aole.object;

import aole.math.Ray3;
import aole.math.Vec3;
import aole.plugin.VQCamera;

public class CameraPinhole implements VQCamera {
	// origin / eye point /focal point
	private Vec3 origin;
	// lookat point
	private Vec3 lookat = new Vec3(0f, 0f, 0f);
	// up vector
	private Vec3 up = new Vec3(0f, 1f, 0f);
	// field of view in radians
	private float fov = (float) (Math.toRadians(45));
	// aspect ratio
	private float ratio;
	// output image width and height
	private int width = 800;
	private int height = 600;

	// lookat rays
	private Vec3 ln, u, v;

	public CameraPinhole() {
		this(new Vec3(0f, 0f, -10f));
	}

	public CameraPinhole(Vec3 o) {
		origin = o;
	}

	public void preCompute () {
		// aspect ratio
		ratio = width / (float) height;
		// compute look at direction
		ln = lookat.getSubtracted(origin);
		ln.normalize();

		// compute u,v directions
		u = Vec3.cross(up, ln);
		u.normalize();

		v = Vec3.cross(ln, u);
		v.normalize();

		// compute u,v
		float tan2 = (float) Math.tan(fov / 2f);
		u.scale(tan2);
		v.scale(tan2 / ratio);
	}

	public void getViewRay (float x, float y, Ray3 ray) {
		ray.orig = origin;
		ray.dir = ln.getAdded(u.getScaled(x));
		ray.dir.add(v.getScaled(y));
	}

	/* (non-Javadoc)
	 * @see aole.plugin.VQCamera#getHeight()
	 */
	public int getHeight () {
		return height;
	}

	/* (non-Javadoc)
	 * @see aole.plugin.VQCamera#getWidth()
	 */
	public int getWidth () {
		return width;
	}

	/* (non-Javadoc)
	 * @see aole.plugin.VQCamera#getOrigin()
	 */
	@Override
	public Vec3 getOrigin () {
		return origin;
	}
}
